package es.wtestgen.services;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.hibernate.criterion.Restrictions;

import es.wtestgen.bean.profesor.PreguntaForm;
import es.wtestgen.domain.Asignatura;
import es.wtestgen.domain.Pregunta;
import es.wtestgen.domain.Respuesta;
import es.wtestgen.util.HibernateUtil;

public class PreguntaDAO {
		
		private static final Log log = LogFactory.getLog(PreguntaDAO.class);
		
		public PreguntaDAO(){
			
		}
		
		
		public boolean eliminar(int codPreg){
			Transaction tx = null;
			Session session = HibernateUtil.currentSession();
			boolean eliminado = false;
			try{			
				tx = session.beginTransaction();
				Pregunta pregunta = (Pregunta)session.get(Pregunta.class, codPreg);
				Asignatura asignatura = (Asignatura)session.get(Asignatura.class, pregunta.getAsignatura().getCodAsig());
				asignatura.getPreguntas().remove(pregunta);
				Set<Respuesta> respuestas = (Set<Respuesta>)pregunta.getRespuestas();
				for (Iterator iterator = respuestas.iterator(); iterator
						.hasNext();) {
					Respuesta respuesta = (Respuesta) iterator.next();
					iterator.remove();					
				}
				session.delete(pregunta);
				tx.commit();
				eliminado = true;
			}catch(Exception e){
				try{
					tx.rollback();
					e.printStackTrace();
				}catch(Exception e2){
					e2.printStackTrace();					
				}
			}finally{
					HibernateUtil.closeSession();
			}
			return eliminado;
		}
		
			
		public List findAll(){
			List lista = new ArrayList();
			Criteria criteria = null;
			
			try{
				Session session = HibernateUtil.currentSession();
				criteria = session.createCriteria(Pregunta.class);				
				lista = criteria.list();		
			}catch(HibernateException e){
				log.error("_____Error al obtener la todos los registros de la clase Pregunta",e);
				throw new HibernateException(e);						
			}	
			return lista;
		}
		
		
		public List findById(String cod){
			List lista = new ArrayList();
			Criteria criteria = null;
			int id = Integer.parseInt(cod);
			
			try{
				Session session = HibernateUtil.currentSession();
				criteria = session.createCriteria(Pregunta.class);				
				criteria.add(Restrictions.eq("codPreg", id));
				lista = criteria.list();		
			}catch(HibernateException e){
				log.error("_____Error al obtener el registro de la clase Pregunta con id: " + cod,e);
				throw new HibernateException(e);						
			}	
			return lista;
		}
		
		
		public List findPreguntasAsignatura(Asignatura asignatura){
			List preguntas = new ArrayList();
			Criteria criteria = null;
			
			try{
				Session session = HibernateUtil.currentSession();
				
				Asignatura asig = (Asignatura)session.get(Asignatura.class, asignatura.getCodAsig());
				criteria = session.createCriteria(Pregunta.class);
				criteria.add(Restrictions.eq("asignatura", asig));
				preguntas =  criteria.list();

			}catch(HibernateException e){
				log.error("_____Error al obtener las preguntas de la asignatura: "+ asignatura.getNombreAsig() ,e);
				throw new HibernateException(e);						
			}	
			
			return preguntas;
			
		}
		
		
		public boolean guardarPreguntaEnAsignatura(Pregunta preg,int codAsig){
			Transaction tx = null;
			Session session = HibernateUtil.currentSession();
			boolean guardado = false;
			try{			
				tx = session.beginTransaction();
				session.clear();
				//session.flush();
								
				Asignatura asignatura = (Asignatura)session.get(Asignatura.class,codAsig);
				if(preg.getCodPreg() != -1){
					Pregunta pregunta = (Pregunta)session.get(Pregunta.class,preg.getCodPreg());
					pregunta.setEnunciadoPreg(preg.getEnunciadoPreg());
					pregunta.setDificultad(preg.getDificultad());
					pregunta.setAsignatura(asignatura);
					session.saveOrUpdate(pregunta);
					asignatura.getPreguntas().add(pregunta);				
				}else{
					preg.setAsignatura(asignatura);
					session.saveOrUpdate(preg);
					asignatura.getPreguntas().add(preg);
				}
				
				session.saveOrUpdate(asignatura);
				
				tx.commit();
				guardado = true;
			}catch(Exception e){
				try{
					tx.rollback();
					e.printStackTrace();
				}catch(Exception e2){
					e2.printStackTrace();					
				}
			}finally{
					HibernateUtil.closeSession();
			}
			return guardado;
		}
		
		
		/**
		 * Método que guarda una pregunta de manera persistente y además sus respuestas asociadas
		 * pasadas con un Set también se guardarán
		 */

		
		public boolean guardarPreguntaEnAsignaturaConRespuestas(Pregunta preg,int codAsig, Set<Respuesta> respuestasEnSesion){
			Transaction tx = null;
			Session session = HibernateUtil.currentSession();
			boolean guardado = false;
			RespuestaDAO respuestaDao = new RespuestaDAO();
			try{			
				tx = session.beginTransaction();
				session.clear();
				//session.flush();
								
				Asignatura asignatura = (Asignatura)session.get(Asignatura.class,codAsig);
				if(preg.getCodPreg() != -1){
					Pregunta pregunta = (Pregunta)session.get(Pregunta.class,preg.getCodPreg());
					pregunta.setEnunciadoPreg(preg.getEnunciadoPreg());
					pregunta.setDificultad(preg.getDificultad());
					pregunta.setAsignatura(asignatura);
					session.saveOrUpdate(pregunta);
					asignatura.getPreguntas().add(pregunta);
					
					/*
					 * tratamos las respuestas
					 */
					
					for (Iterator iterator = respuestasEnSesion.iterator(); iterator
					.hasNext();) {
						Respuesta respuesta = (Respuesta) iterator.next();
						Respuesta respuestaPersistente = (Respuesta)session.get(Respuesta.class, respuesta.getCodResp());
						if(respuestaPersistente == null){
							respuesta.setCodResp(-1);
							respuesta.setPregunta(pregunta);
							session.saveOrUpdate(respuesta);
							pregunta.getRespuestas().add(respuesta);							
							session.saveOrUpdate(pregunta);							
						}else{
							respuestaPersistente.setPregunta(pregunta);
							respuestaPersistente.setRespuestaResp(respuesta.getRespuestaResp());
							respuestaPersistente.setEsCorrecta(respuesta.isEsCorrecta());
							session.saveOrUpdate(respuestaPersistente);
							pregunta.getRespuestas().add(respuestaPersistente);	
							session.saveOrUpdate(pregunta);						
						}
					}
					
				}else{
					preg.setAsignatura(asignatura);
					session.saveOrUpdate(preg);
					asignatura.getPreguntas().add(preg);
					
					/*
					 * tratamos las respuestas
					 */
					
					for (Iterator iterator = respuestasEnSesion.iterator(); iterator
					.hasNext();) {
						Respuesta respuesta = (Respuesta) iterator.next();
						Respuesta respuestaPersistente = (Respuesta)session.get(Respuesta.class, respuesta.getCodResp());
						if(respuestaPersistente == null){
							respuesta.setCodResp(-1);
							
							Pregunta pregunta = (Pregunta)session.get(Pregunta.class,preg.getCodPreg());
							
							respuesta.setPregunta(pregunta);
							session.saveOrUpdate(respuesta);
							pregunta.getRespuestas().add(respuesta);
							session.saveOrUpdate(pregunta);
							
						}else{
							
							Pregunta pregunta = (Pregunta)session.get(Pregunta.class,preg.getCodPreg());
							respuestaPersistente.setPregunta(pregunta);
							respuestaPersistente.setRespuestaResp(respuesta.getRespuestaResp());
							respuestaPersistente.setEsCorrecta(respuesta.isEsCorrecta());
							session.saveOrUpdate(respuestaPersistente);
							
							pregunta.getRespuestas().add(respuestaPersistente);
							session.saveOrUpdate(pregunta);
							
						}
					}
				}
				
				session.saveOrUpdate(asignatura);
				
				
				tx.commit();
				guardado = true;
			}catch(Exception e){
				try{
					tx.rollback();
					e.printStackTrace();
				}catch(Exception e2){
					e2.printStackTrace();					
				}
			}finally{
					HibernateUtil.closeSession();
			}
			return guardado;
		}
		
		
		public List findByParameters(PreguntaForm preguntaForm){
			List lista = new ArrayList();
			Criteria criteria = null;
			
			try{
				Session session = HibernateUtil.currentSession();
				criteria = session.createCriteria(Pregunta.class);				
				
				if(preguntaForm.getEnunciadoPreg() != null && !"".equals(preguntaForm.getEnunciadoPreg())){
					criteria.add(Restrictions.like("enunciadoPreg","%" + preguntaForm.getEnunciadoPreg() + "%"));
				}
				if(preguntaForm.getCodAsig() != 0){
					AsignaturaDAO asignaturaDao = new AsignaturaDAO();
					Asignatura asignatura = (Asignatura)asignaturaDao.findById(String.valueOf(preguntaForm.getCodAsig())).get(0);
					criteria.add(Restrictions.eq("asignatura", asignatura));				
				}
				if(preguntaForm.getDificultad() != 0){
					criteria.add(Restrictions.eq("dificultad", preguntaForm.getDificultad()));				
				}			
				
				lista = criteria.list();		
			}catch(HibernateException e){
				log.error("_____Error al obtener los registros de la clase Pregunta para los parametros de busquedas." ,e);
				throw new HibernateException(e);						
			}	
			return lista;
		}
}
